#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <iostream>
#include "gaussian.h"



using namespace std;
using namespace cv;


 
Gaussian::Gaussian(int size, float sigma){

  Mat img, Gimg;
  int i, j, p, q, m, ch, value, nRows, nCols;
  float sum;
  float kernel[size][size];
  string imgPath = "../pic/1.jpg";
  string GimgPath = "../pic/Gimg.jpg";
  
  /* 确保输入参数正常 */
  if (size <= 0 || sigma == 0)
	  cout << "Gaussian with size or sigma error" << endl;
	  //assert(0);
	
  /* 读取图片 */
  img = imread(imgPath);
  nRows = img.rows;
	nCols = img.cols;
  cout << "read image ok." << "  width: " << nRows << "  heigh: " << nCols << endl;
  
  /* 获取高斯核 */
  sum = 0;
  m = (size+1)/2;//这里对高斯公式做了改动，是为了将高斯核中心放到矩阵的中心，x --> x-size/2，y --> y-size/2
	for(i = 0; i < size; i++){
		for(j = 0; j < size; j++){
			kernel[i][j] = (1 / (2 * 3.1415927 * sigma * sigma)) * 
			               exp(-((i - m + 1) * (i - m + 1) + (j - m + 1) * (j - m + 1)) / (2 * sigma * sigma));
			sum += kernel[i][j];
		}
	}
	for(i = 0; i < size; i++){
		for(j = 0; j < size; j++){
			kernel[i][j] /= sum;
		}
	}
	for(i = 0; i < size; i++){
		for(j = 0; j < size; j++){
			printf("%5f ",kernel[i][j]);
		}
		printf("\n");
  }
	cout << "Gaussian kernel ok" << endl;
  
  /* 高斯滤波 */
  Gimg = img;
  for(ch = 0; ch < 3; ch++){//对应RGB三通道
    for (i = m; i < nRows-m; i++){//i j 对应像素坐标，边缘不做处理
      for (j = m; j < nCols-m; j++){
      
        value = 0;
        for (p = 0; p < size; p++){//p q 对应卷积核
          for (q = 0; q < size; q++){
          
            value += img.at<Vec3b>(i-m+p, j-m+q)[ch] * kernel[p][q];
          }  
        }  
        Gimg.at<Vec3b>(i, j)[ch] = value;
      }
    }
  }
  cout << "Gaussian filter ok" << endl;
  
  /* 保存图片 */
  imwrite(GimgPath, Gimg);
  cout << "save Gaussian img ok." << endl;
}


Gaussian::~Gaussian(void){
  cout << "byby ~~~ I'm jianbao" << endl;
}





